--
-- @Author:      name
-- @DateTime:    2018-03-30 23:05:48
-- @Description: 消息的处理

local skynet = require "skynet"

local log = require "Logger"
local config = require "configquery"
local ProtoLoader = require "ProtoLoader"
local MessageSession = require "manager.MessageSession"




local MessageHandler = class("MessageHandler")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function MessageHandler:ctor(message_dispatch, node_message)

	self.proto_file = skynet.getenv("proto_config") --proto文件路径	
    self.server_id = tonumber(skynet.getenv("server_id"))
    self.server_type = skynet.getenv("server_type") or ""
    self.server_name = skynet.getenv("server_name") or ""
    self.cluster_addr = skynet.getenv("cluster_addr")
    self.cluster_name = skynet.getenv("cluster_name")
	self.server_addr = skynet.getenv("server_addr")
	self.port_socket = tonumber(skynet.getenv("port_socket"))
	self.port_websocket = tonumber(skynet.getenv("port_websocket"))
	
    self.zone_cluster_id = skynet.getenv("zone_cluster_id")
    self.node_cluster_id = skynet.getenv("node_cluster_id")
    self.login_cluster_id = skynet.getenv("login_cluster_id")

	self.message_dispatch = message_dispatch	
	self.node_message = node_message

	self.proto_loader = ProtoLoader.new() --proto加载
	self.message_session = MessageSession.new() --socket会话



	self:register()
end

--注册本服务里的消息
function MessageHandler:register()

	self.message_dispatch:registerSelf('start', handler(self,self.start))
	--socket status message
	self.message_dispatch:registerSelf('socket', handler(self.message_session,self.message_session.dispatch))
	--back server message
	self.message_dispatch:registerSelf('kick_user', handler(self,self.onKickUser))
	self.message_dispatch:registerSelf('disconnect', handler(self,self.onDisconnect))

	--服务间消息
	self.message_dispatch:registerSelf('check_login', handler(self,self.onCheckUserLogin))
	self.message_dispatch:registerSelf('user_login', handler(self,self.onUserLogin))
	self.message_dispatch:registerSelf('user_logout', handler(self,self.onUserLogout))

	self.message_dispatch:registerSelf('message_to_node', handler(self,self.messageToNode))

	self.message_dispatch:registerSelf('server_register_res', handler(self,self.serverRegisterRes))
	self.message_dispatch:registerSelf('message_to_user_nt', handler(self,self.messageToUserNt))
	self.message_dispatch:registerSelf('message_to_users_nt', handler(self,self.messageToUsersNt))


end

-- 向节点服务器注册
function MessageHandler:serverRegisterReq()
    local server_info = {
        server_id = self.server_id,
        server_type = self.server_type,
        server_name = self.server_name,
        cluster_addr = self.cluster_addr,
        cluster_name = self.cluster_name,
    }
    local node = self.node_cluster_id
    if self.login_cluster_id then 
    	node = self.login_cluster_id
    end
    self.node_message:sendNodeProxy(node, "server_register_req", server_info)     
end

function MessageHandler:sendServerInfo()
   local server_info = {
        server_id = self.server_id,
        server_type = self.server_type,
        server_name = self.server_name,
        cluster_addr = self.cluster_addr,
        cluster_name = self.cluster_name,        
        max_client = self.server_manager:getMaxClient(),
        online_count = self.server_manager:getOnlineCount(),
		server_port = self.port_socket,
		server_wport = self.port_websocket,      
		server_addr = self.server_addr,  
    }   
    self.node_message:sendNodeProxy(self.zone_cluster_id, "server_info_nt", server_info)
end







---------------------------------------------------------
-- CMD
---------------------------------------------------------
function MessageHandler:start()
	local setting = config.setting_cfg
	local svr_id = tonumber(skynet.getenv("svr_id")) --服务器名
	local svr_name = skynet.getenv("svr_name") --服务器类型
	-- local svr_info = setting[svr_name][svr_id]

	local maxclient = tonumber(skynet.getenv("maxclient"))
	local gate_num = tonumber(skynet.getenv("gate_num"))
	local pbc_env = self.proto_loader:init(self.proto_file, {'common','game','gate','web','zone','hall',})

	--初始化
	self.node_message:initProto(pbc_env)
	self.server_manager = global.server_manager

	--skynet控制台
	-- skynet.newservice("debug_console",server_config.debug_port)

	--启动socket gate
	local conf = {
			port = self.port_socket,
			maxclient = maxclient,
			nodelay = true,
		}		
	local gate = skynet.newservice("gate")
	log.debug('_____________manager open socket gate port:'.. conf.port)
	skynet.call(gate, "lua", "open", conf)

	--启动websocket gate
	local ws_conf = {
			port = self.port_websocket,
			maxclient = maxclient,
			nodelay = true,
		}
	local wsgate = skynet.newservice("wsgate")
	log.debug('_____________manager open websocket gate port:'.. ws_conf.port)
	skynet.call(wsgate, "lua", "open", ws_conf)

	--socket消息处理
	local gate_service
	for i = 1, gate_num do
		gate_service = skynet.newservice("gate_service")		
		self.message_session:addSessionService(gate_service)
		skynet.call(gate_service, 'lua', 'init', pbc_env)
	end

	self:serverRegisterReq()

end

--检测用户登陆
function MessageHandler:onCheckUserLogin(user_id, session_id)
	local session = self.message_session:getSessionByUserId(user_id)
	if not session then
		return false
	end	
	--已登录
	return true
end

--用户token登陆成功
function MessageHandler:onUserLogin(user_id, session_id)
	local res = self.message_session:bindSession(user_id,session_id)
	if not res then 
		log.debug("_________绑定__user_id session 失败____",user_id, session_id)
		return 
	end
	--更新服务器信息到zone
	self.server_manager:increaseOnlineCount()
	self:sendServerInfo()	
end

--用户登出
function MessageHandler:onUserLogout(user_id, session_id)
	--发送
	local cmd = config.message_cmd
	local session = self.message_session:getSession(session_id)
	if not session then 
		return 
	end
	local data = {
		error_code = 0,
		error_msg = "登出成功"	
	}
	self.node_message:sendClient(session.fd, session.contype, "logoutRes", data)
	self.message_session:removeSession(session_id)
	self.message_session:unbindSession(user_id)
end

--踢指定用户下线
function MessageHandler:onKickUser(fd)
	local session = self.message_session:getSession(fd)
	if session and session.service then 
		log.debug("_____踢用户出线_______kick_user_fd_",fd)
		self.node_message:sendService(session.service, "disconnect", fd)
	end
	-- if session.agent then 
	-- 	self.node_message:sendService(session.agent, "kick", fd)
	-- end
	self.message_session:removeSession(fd)
end

--断线
function MessageHandler:onDisconnect(fd, user_id)
	print("____onDisconnect___",fd, user_id)
	--更新服务器信息到zone
	self.server_manager:decreaseOnlineCount()
	self:sendServerInfo()	
	--大厅断线通知
	--游戏断线通知	
end

--nodeserver 返回注册成功
function MessageHandler:serverRegisterRes(msg_data)
    print("__serverRegisterRes___",msg_data)
    local server_info = {
        server_id = self.server_id,
        server_type = self.server_type,
        server_name = self.server_name,
        cluster_addr = self.cluster_addr,
        cluster_name = self.cluster_name,        
        max_client = self.server_manager:getMaxClient(),
        online_count = self.server_manager:getOnlineCount(),
		server_port = self.port_socket,
		server_wport = self.port_websocket,      
		server_addr = self.server_addr,  
    }   

    self.node_message:sendNodeProxy(self.zone_cluster_id, "server_info_nt", server_info)
end

--踢除指定会话
function MessageHandler:onKickSession(session_id)
	local session = self.message_session:getSession(session_id)
	if session then 
		log.debug("_________MessageHandler:onKickSession___________session_id:",session_id)
		self.node_message:sendService(session.service, "kick_connect", session_id)
	end
end

--消息推送到user
function MessageHandler:messageToUserNt(user_id, message_name, msg_data)
    -- print("____messageToUser____", message_name, msg_data)
	local session = self.message_session:getSessionByUserId(user_id)
	if not session then
		return false
	end	
	-- print("____session____", session)	
	self.node_message:sendClient(session.fd, session.contype, message_name, msg_data)
end

--消息推送到users
function MessageHandler:messageToUsersNt(users, message_name, msg_data)
    print("____messageToUsers____", message_name, msg_data)
    if type(users)=="table" then 
    	--给多人转发消息
    	for _,id in pairs(users) do 
			local session = self.message_session:getSessionByUserId(id)
			if session then
				self.node_message:sendClient(session.fd, session.contype, message_name, msg_data)
			end
		end			
    	return true
    end
    return false
end
return MessageHandler